package com.cygsunri.rbac.api;

import com.alibaba.fastjson.JSONObject;
import com.cygsunri.rbac.entity.*;
import com.cygsunri.rbac.service.AccountService;
import com.cygsunri.rbac.service.LoginService;
import com.cygsunri.rbac.service.MenuService;
import com.cygsunri.rbac.service.RoleService;
import com.cygsunri.rbac.util.PasswordHash;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/api/v2/account")
public class AccountController {

    @Autowired
    private LoginService loginService;

    @Autowired
    private AccountService accountService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private MenuService menuService;

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ResponseEntity<LoginResponse> LoginAction(@RequestBody LoginAction loginAction) {
        String status;
        String currentAuthority = "guest";
        String userName = loginAction.getUsername();
        String userID = null;
        HttpStatus retStatus = HttpStatus.OK;
        if (loginService.checkPassword(userName, loginAction.getPassword())) {
            status = "ok";
            Account account = accountService.getAccountByName(userName);
//            Role role = account.getRole();
//            currentAuthority = role.;
            currentAuthority = userName;
            userID = account.getId();
        } else {
            status = "error";
            retStatus = HttpStatus.UNAUTHORIZED;
        }
        LoginResponse loginAccount = new LoginResponse(status, loginAction.getType(), userName, userID, currentAuthority);

        return new ResponseEntity<>(loginAccount, retStatus);
    }

    @RequestMapping(value = "/changePassword", method = RequestMethod.POST)
    public ResponseEntity<String> changePassword(@RequestBody PasswordAction passwordAction) {

        Account account = accountService.getById(passwordAction.getUserID());

        if (account == null) {
            return new ResponseEntity<>("找不到该用户!", HttpStatus.NOT_FOUND);
        }

        if (!loginService.checkPassword(account, passwordAction.getOldPassword())) {
            return new ResponseEntity<>("旧密码错误!", HttpStatus.BAD_REQUEST);
        }

        try {
            String pwdHash = PasswordHash.createHash(passwordAction.getNewPassword());
            if (StringUtils.isNotBlank(pwdHash)) {
                String[] pwd = pwdHash.split(":");
                if (pwd.length == 3) {
                    account.setPassword(pwd[2]);
                    account.setSalt(pwd[1]);

                    accountService.updateById(account);
                    return new ResponseEntity<>("修改密码成功!", HttpStatus.OK);
                }
            }
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }

        return new ResponseEntity<>("未知错误!", HttpStatus.BAD_REQUEST);


    }

    @RequestMapping(value = "/menus", method = RequestMethod.GET)
    public ResponseEntity<List<JSONObject>> getAccountMenus(@RequestParam("username") String name) {
        List<JSONObject> menus = new ArrayList<>();
        Account account = accountService.getAccountByName(name);
        if (account != null && account.getRole() != null) {
            menus = menuService.getMenuListByRole(account.getRole().getId());
        }
        return new ResponseEntity<>(menus, HttpStatus.OK);
    }

//    @RequestMapping(value = "/{userName}", method = RequestMethod.GET)
//    public ResponseEntity<Account> AccountInfo(@PathVariable("userName") String userName) {
//        return new ResponseEntity<>(accountService.getAccountByName(userName), HttpStatus.OK);
//    }

//    @RequestMapping(value = "/check/{userName}/{password}", method = RequestMethod.POST)
//    public ResponseEntity checkUser(@PathVariable("userName") String userName, @PathVariable("password") String password) {
//        return new ResponseEntity(loginService.checkPassword(accountService.getAccountByName(userName), password) ? HttpStatus.OK : HttpStatus.FORBIDDEN);
//    }



//    @RequestMapping(value = "menus/users/{name}", method = RequestMethod.GET)
//    public ResponseEntity<List<JSONObject>> getAccountMenus(@PathVariable("name") String name) {
//        List<JSONObject> menus = new ArrayList<>();
//        Account account = accountService.getAccountByName(name);
//        if (account != null && account.getRole() != null) {
//            menus = menuService.getMenuListByRole(account.getRole().getId());
//        }
//        return new ResponseEntity<>(menus, HttpStatus.OK);
//    }

    @RequestMapping(value = "/accounts/users/{user}", method = RequestMethod.GET)
    public ResponseEntity<List<Account>> AccountInfoList(@PathVariable("user") String user) {
        return new ResponseEntity<>(accountService.list(), HttpStatus.OK);
    }

    @RequestMapping(value = "/roles", method = RequestMethod.GET)
    public ResponseEntity<List<Role>> AccountRoleList() {
        return new ResponseEntity<>(roleService.list(), HttpStatus.OK);
    }

    @RequestMapping(value = "/account/delete/{user}", method = RequestMethod.POST)
    public ResponseEntity<Boolean> delAccount(@PathVariable("user") String user) {
        accountService.removeById(user);
        return new ResponseEntity<>(true, HttpStatus.OK);
    }

    @RequestMapping(value = "/account/add/users/{user}", method = RequestMethod.POST)
    public ResponseEntity<Boolean> addAccount(@PathVariable("user") String user, @RequestBody AccountAction accountAction) {

        Account account = new Account();

        account.setUsername(accountAction.getUsername());
        account.setArea(accountAction.getArea());
        account.setRealName(accountAction.getRealname());
        account.setCreatorId(user);

        if (accountAction.getRoleId() != null) {
            account.setRole(roleService.getById(accountAction.getRoleId()));
        }

        account.setCreateTime(new Date());

        try {
            String pwdHash = PasswordHash.createHash(accountAction.getPassword().trim());
            if (StringUtils.isNotBlank(pwdHash)) {
                String[] pwd = pwdHash.split(":");
                if (pwd != null && pwd.length == 3) {
                    account.setPassword(pwd[2]);
                    account.setSalt(pwd[1]);
                }
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }

        accountService.save(account);

        return new ResponseEntity<>(true, HttpStatus.OK);
    }

    @RequestMapping(value = "/account/update/users/{user}", method = RequestMethod.POST)
    public ResponseEntity<Boolean> updateAccount(@PathVariable("user") String user, @RequestBody AccountAction accountAction) {

        Account account = accountService.getById(accountAction.getId());

        account.setUsername(accountAction.getUsername());
        account.setArea(accountAction.getArea());
        account.setRealName(accountAction.getRealname());
        account.setModifierId(user);

        if (accountAction.getRoleId() != null) {
            account.setRole(roleService.getById(accountAction.getRoleId()));
        }

        account.setModifyTime(new Date());

        if (!accountAction.getPassword().isEmpty()) {

            try {
                String pwdHash = PasswordHash.createHash(accountAction.getPassword().trim());
                if (StringUtils.isNotBlank(pwdHash)) {
                    String[] pwd = pwdHash.split(":");
                    if (pwd != null && pwd.length == 3) {
                        account.setPassword(pwd[2]);
                        account.setSalt(pwd[1]);
                    }
                }
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (InvalidKeySpecException e) {
                e.printStackTrace();
            }
        }

        boolean upCnt = accountService.updateById(account);

        if (upCnt && account.getRole() != null) {
            account.getRole().setModifierId(user);
            account.getRole().setModifyTime(new Date());
            roleService.updateById(account.getRole());
        }

        return new ResponseEntity<>(true, HttpStatus.OK);

    }

}
